﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MapViewer
{
    public class MapViewerController
    {
        private readonly IMapViewer _viewer;
        private readonly IMapLegend _legend;
        private readonly IMapStatusBar _statBar;

        public MapViewerController(IMapViewer viewer, IMapLegend legend, IMapStatusBar statBar)
        {
            if (viewer == null)
                throw new ArgumentNullException("viewer");

            if (legend == null)
                throw new ArgumentNullException("legend");

            if (statBar == null)
                throw new ArgumentNullException("statBar");

            _viewer = viewer;
            _legend = legend;
            _statBar = statBar;

            WireEvents();
        }

        private void WireEvents()
        {
            _viewer.MapRefreshed += new EventHandler(OnMapRefreshed);
            _viewer.MapScaleChanged += new EventHandler(OnMapScaleChanged);
            _viewer.SelectionChanged += new EventHandler(OnMapSelectionChanged);
            _viewer.MapActiveToolChanged += new EventHandler(OnActiveToolChanged);
            _viewer.ViewerInitialized += new EventHandler(OnViewerInitialized);
            _legend.VisibilityChanged += new EventHandler(OnLegendVisibilityChanged);
            _viewer.MouseMapPositionChanged += new EventHandler<MapPointEventArgs>(OnMouseMapPositionChanged);
        }

        void OnMouseMapPositionChanged(object sender, MapPointEventArgs e)
        {
            _statBar.SetCursorPositionMessage(string.Format("X: {0}, Y: {1}", e.X, e.Y));
        }

        void OnLegendVisibilityChanged(object sender, EventArgs e)
        {
            _viewer.RefreshMap(false);
        }

        void OnViewerInitialized(object sender, EventArgs e)
        {
            ((MgLegend)_legend).Init(_viewer.GetMap());
        }

        void OnActiveToolChanged(object sender, EventArgs e)
        {
            System.Diagnostics.Trace.TraceInformation("Active tool set to: " + _viewer.ActiveTool);
        }

        void OnMapSelectionChanged(object sender, EventArgs e)
        {
            var sel = _viewer.GetSelection();
            int selTotal = 0;
            var selLayers = sel.GetLayers();
            for (int i = 0; i < selLayers.GetCount(); i++)
            {
                var layer = selLayers.GetItem(i);
                selTotal += sel.GetSelectedFeaturesCount(layer, layer.FeatureClassName);
            }
            _statBar.SetFeatureSelectedMessage(string.Format("{0} features selected", selTotal));
        }

        void OnMapScaleChanged(object sender, EventArgs e)
        {
            var map = _viewer.GetMap();
            double scale = map.ViewScale;

            _legend.SetScale(scale);
            _statBar.SetMapScaleMessage(string.Format("1:{0}", scale));
        }

        void OnMapRefreshed(object sender, EventArgs e)
        {
            _legend.RefreshLegend();

            var map = _viewer.GetMap();
            _statBar.SetMapScaleMessage("1:" + map.ViewScale);
            var ext = map.MapExtent;
            _statBar.SetMapSizeMessage(string.Format("{0} x {1}", ext.Width, ext.Height));
            var sel = _viewer.GetSelection();
            _statBar.SetFeatureSelectedMessage(string.Format("{0} features selected", GetTotalSelectionCount(sel)));
        }

        private static int GetTotalSelectionCount(OSGeo.MapGuide.MgdSelection sel)
        {
            int total = 0;
            if (sel != null)
            {
                var layers = sel.GetLayers();
                if (layers != null)
                {
                    for (int i = 0; i < layers.GetCount(); i++)
                    {
                        var layer = layers.GetItem(i);
                        total += sel.GetSelectedFeaturesCount(layer, layer.FeatureClassName);
                    }
                }
            }
            return total;
        }
    }
}
